﻿#ifndef __ThreadDefines_H__
#define __ThreadDefines_H__
#pragma once

#include "kernel/threading/mutex.h"
#include "kernel/threading/readwritelock.h"
#include "kernel/threading/thread.h"
//#include "kernel/OgreMemoryallocatorconfig.h"

#if OGRE_THREAD_SUPPORT

#define OGRE_AUTO_MUTEX mutable FD::Kernel::RecursiveMutex OGRE_AUTO_MUTEX_NAME;
#define OGRE_LOCK_AUTO_MUTEX FD::Kernel::MutexLocker _AutoMutexLocker(&OGRE_AUTO_MUTEX_NAME);

#define OGRE_MUTEX(name) mutable FD::Kernel::RecursiveMutex name;
#define OGRE_STATIC_MUTEX(name) static FD::Kernel::RecursiveMutex name;
#define OGRE_STATIC_MUTEX_INSTANCE(name) FD::Kernel::RecursiveMutex name;
#define OGRE_LOCK_MUTEX(name) FD::Kernel::MutexLocker _NameLocker(&name);
#define OGRE_LOCK_MUTEX_NAMED(mutexName, _LockName) FD::Kernel::MutexLocker _LockName(&mutexName);

///指针实现
#define OGRE_AUTO_SHARED_MUTEX        mutable FD::Kernel::RecursiveMutex *OGRE_AUTO_MUTEX;
#define OGRE_LOCK_AUTO_SHARED_MUTEX   OgreAssert(OGRE_AUTO_MUTEX); FD::Kernel::MutexLocker _AutoMutexLocker(OGRE_AUTO_MUTEX);
#define OGRE_NEW_AUTO_SHARED_MUTEX    OgreAssert(!OGRE_AUTO_MUTEX); OGRE_AUTO_MUTEX = new FD::Kernel::RecursiveMutex();
#define OGRE_DELETE_AUTO_SHARED_MUTEX  OgreAssert(OGRE_AUTO_MUTEX); delete OGRE_AUTO_MUTEX;
#define OGRE_COPY_AUTO_SHARED_MUTEX(from)  OgreAssert(!OGRE_AUTO_MUTEX); OGRE_AUTO_MUTEX = from;
#define OGRE_SET_AUTO_SHARED_MUTEX_NULL    OGRE_AUTO_MUTEX = 0;
#define OGRE_MUTEX_CONDITIONAL(name)   if (name)

#define OGRE_RW_MUTEX(name)   mutable FD::Kernel::ReadWriteLock name;
#define OGRE_LOCK_RW_MUTEX_READ(name)    FD::Kernel::ReadLocker name##locker(&name);
#define OGRE_LOCK_RW_MUTEX_WRITE(name)    FD::Kernel::WriteLocker name##locker(&name);

/// Thread-local pointer
#define OGRE_THREAD_POINTER(T, var) FD::Kernel::ThreadLocalStore<T> var
#define OGRE_THREAD_POINTER_INIT(var) var()
#define OGRE_THREAD_POINTER_VAR(T, var) FD::Kernel::ThreadLocalStore<T> var
#define OGRE_THREAD_POINTER_SET(var, expr) var.setValue(expr)
#define OGRE_THREAD_POINTER_GET(var) var.getValue()
#define OGRE_THREAD_POINTER_DELETE(var) var.reset()
/// Thread objects and related functions
#define OGRE_THREAD_TYPE FD::Kernel::Thread
#define OGRE_THREAD_CREATE(name, worker) FD::Kernel::Thread *name = OGRE_NEW FD::Kernel::Thread(); name->work(worker);
#define OGRE_THREAD_DESTROY(name) OGRE_DELETE name;
#define OGRE_THREAD_HARDWARE_CONCURRENCY 2
#define OGRE_THREAD_CURRENT_ID FD::Kernel::Thread::getThreadID()
#define OGRE_THREAD_WORKER_INHERIT : public FD::Kernel::ThreadFunc
#define OGRE_THREAD_SYNCHRONISER(sync) FD::Kernel::Condition sync;
#define OGRE_THREAD_WAIT(sync, mutex, lock) sync.wait(mutex);
#define OGRE_THREAD_NOTIFY_ONE(sync) sync.notify_one();
#define OGRE_THREAD_NOTIFY_ALL(sync) sync.notify_all();
/// Utility
#define OGRE_THREAD_SLEEP(ms) FD::Kernel::Thread::sleep(ms);
#else
#define OGRE_LOCK_AUTO_MUTEX
//#define AUTO_MUTEX_LOCKER
#define OGRE_MUTEX(name)
#define OGRE_STATIC_MUTEX(name)
#define OGRE_STATIC_MUTEX_INSTANCE(name)
#define OGRE_LOCK_MUTEX(name)
#define OGRE_LOCK_MUTEX_NAMED(mutexName, _LockName)
#define OGRE_AUTO_SHARED_MUTEX
#define OGRE_LOCK_AUTO_SHARED_MUTEX
#define OGRE_NEW_AUTO_SHARED_MUTEX
#define OGRE_DELETE_AUTO_SHARED_MUTEX
#define OGRE_COPY_AUTO_SHARED_MUTEX(from)
#define OGRE_SET_AUTO_SHARED_MUTEX_NULL
#define OGRE_MUTEX_CONDITIONAL(name) if(true)
#define OGRE_RW_MUTEX(name)
#define OGRE_LOCK_RW_MUTEX_READ(name)
#define OGRE_LOCK_RW_MUTEX_WRITE(name)
#define OGRE_THREAD_SYNCHRONISER(sync)
#define OGRE_THREAD_WAIT(sync, lock)
#define OGRE_THREAD_NOTIFY_ONE(sync)
#define OGRE_THREAD_NOTIFY_ALL(sync)
#define OGRE_THREAD_POINTER(T, var) T* var
#define OGRE_THREAD_POINTER_INIT(var) var(0)
#define OGRE_THREAD_POINTER_VAR(T, var) T* var = 0
#define OGRE_THREAD_POINTER_SET(var, expr) var = expr
#define OGRE_THREAD_POINTER_GET(var) var
#define OGRE_THREAD_POINTER_DELETE(var) { OGRE_DELETE var; var = 0; }
#define OGRE_THREAD_SLEEP(ms)
#define OGRE_THREAD_WORKER_INHERIT
#endif
#endif
